<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> -->
    <script src="../node_modules/vue/dist/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <!-- 使用vue 实现的数据双向绑定效果 -->
        <p>{{username}}</p>
        <input type="text" v-model="username">

        <!--原生js  -->
        <p id="jsdomp"></p>
        <input id="jsdominp" type="text" oninput="changevalueFn(this.value)">
    </div>
</body>

</html>
<script>
    const { createApp } = Vue;
    const vm = createApp({
        data() {
            return {
                message1: 'Hello',
                username: '小岳岳'
            }
        }
    }).mount('#app')


    //01: 模仿vue定义一个初始对象,存放初始的数据
    let obj = {
        username: '孙越',
        age: 20
    }

    // 02: 使用Object.defineProperty监听代理对象, 从而实现达到修改原对象的目的
    // 定义一个监听函数
    function observe(target, fn) {
        // 参数1:target是目标对象, 此时表示的是就是 obj对象
        // 参数2:dom 处理函数
        // 定义一个代理对象,也叫数据劫持对象, 此时就是 result
        let result = {};
        Object.defineProperty(result, 'username', {
            get() {
                // 当访问result对象的username属性时触发,
                return target.username
            },
            set(val) {
                // 当修改result 对象的属性时, 触发set方法
                target.username = val
                // 重新更新dom 
                fn(result)
            }
        })

        // 初始化调用fn 函数
        fn(result);
        // 将result 返出去
        return result
    }

    // 调用观察者函数 observe //此时 res 就是result
    let res = observe(obj, (result) => {
        // 获取元素标签,
        document.querySelector('#jsdomp').innerHTML = result.username;
        // 给inout赋值
        document.querySelector('#jsdominp').value = result.username;
    })

    // 输入框变化的函数
    function changevalueFn(val) {
        console.log(val);
        // 要修改result 这个代理对象
        res.username = val
    }


    // 整理话术:
    // vue2实现双向数据绑定的原理
    // 使用object.defineProperty监听一个代理对象的属性的变化, 该代理对象代理的是vuedata对象中的数据,
    // 当 访问代理对象的属性时, 触发object.defineProperty 上的get方法,从而得到原对象上的数据/属性
    // 当修改代理对象上的属性时. 触发set 方法, 达到修改原对象属性/数据的目的. 实现对原对象/vue中data
    // 中属性的监听.

    // 


</script>